<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>中俊为 | we harmonyos</title>
    <meta name="generator" content="VuePress 1.9.7">
    <script>
          var _hmt = _hmt || [];
          (function() {
            var hm = document.createElement("script");
            hm.src = "https://hm.baidu.com/hm.js?39485dba914ae63b24732b6a90688f0b";
            var s = document.getElementsByTagName("script")[0];
            s.parentNode.insertBefore(hm, s);
          })();
      </script>
    <link rel="manifest" href="/manifest.webmanifest" crossorigin="use-credentials">
    <meta name="description" content="weharmonyos 鸿蒙论坛 鸿蒙注释 开源鸿蒙 鸿蒙源码 openharmony源码 HarmonyOS源码 HarmonyOS HarmonyOS生态 openharmony开发者文档 鸿蒙生态 鸿蒙系统 华为操作系统 鸿蒙研究站 开放原子开源基金会 百万汉字注解鸿蒙 百篇博客分析鸿蒙">
    <meta property="og:url" content="/blog/17.html">
    <meta property="og:site_name" content="中俊为 | we harmonyos">
    <meta property="og:description" content="本篇关键词：、、、 下载 &gt;&gt; 离线文档.鸿蒙内核源码分析(百篇博客分析.挖透鸿蒙内核).pdf.zip) 进程管理相关篇为: v11.04 鸿蒙内核源码分析(调度故事) | 大郎，该喝药了; v12.03 鸿蒙内核源码分析(进程控制块) | 可怜天下父母心; v13.01 鸿蒙内核源码分析(进程空间) | 有爱的地方才叫家 ; v14.01 鸿蒙内">
    <meta property="og:type" content="article">
    <meta property="og:locale" content="en-US">
    <meta name="twitter:card" content="summary_large_image">
    <meta name="twitter:image:alt" content="中俊为 | we harmonyos">
    <meta name="theme-color" content="#46bd87">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
    
    <link rel="preload" href="/assets/css/0.styles.087eb7d3.css" as="style"><link rel="preload" href="/assets/js/app.9a8b95d8.js" as="script"><link rel="preload" href="/assets/js/vendors~layout-Layout.c1e797d4.js" as="script"><link rel="preload" href="/assets/js/vendors~layout-Blog~layout-Layout~layout-NotFound.f75cf258.js" as="script"><link rel="preload" href="/assets/js/page--ba329370.b5f22d13.js" as="script"><link rel="prefetch" href="/assets/js/160.a8046d43.js"><link rel="prefetch" href="/assets/js/161.29f8564f.js"><link rel="prefetch" href="/assets/js/162.249ee491.js"><link rel="prefetch" href="/assets/js/163.c57d1577.js"><link rel="prefetch" href="/assets/js/164.7a788aaa.js"><link rel="prefetch" href="/assets/js/165.c333afb2.js"><link rel="prefetch" href="/assets/js/166.9bcb7cd6.js"><link rel="prefetch" href="/assets/js/layout-Blog.4a9781d1.js"><link rel="prefetch" href="/assets/js/layout-Layout.7e277e0b.js"><link rel="prefetch" href="/assets/js/layout-NotFound.9326b14e.js"><link rel="prefetch" href="/assets/js/layout-Slide.8dd861e4.js"><link rel="prefetch" href="/assets/js/page--00854288.e2bc8e8a.js"><link rel="prefetch" href="/assets/js/page--00f8db0a.b2a35fe6.js"><link rel="prefetch" href="/assets/js/page--03ad6df0.d48f4c19.js"><link rel="prefetch" href="/assets/js/page--04b12ba8.e8add78d.js"><link rel="prefetch" href="/assets/js/page--070d2528.d24cd503.js"><link rel="prefetch" href="/assets/js/page--086560f0.a6be2844.js"><link rel="prefetch" href="/assets/js/page--090ad32d.fc7da3c3.js"><link rel="prefetch" href="/assets/js/page--0c054030.2886024e.js"><link rel="prefetch" href="/assets/js/page--0d9507c8.a27dee03.js"><link rel="prefetch" href="/assets/js/page--10bd3330.b5165172.js"><link rel="prefetch" href="/assets/js/page--1233b0b2.b5caca9c.js"><link rel="prefetch" href="/assets/js/page--13650e88.61330a2b.js"><link rel="prefetch" href="/assets/js/page--14c850b1.d9a40c31.js"><link rel="prefetch" href="/assets/js/page--15752630.25f9c756.js"><link rel="prefetch" href="/assets/js/page--19150570.58df8995.js"><link rel="prefetch" href="/assets/js/page--19ecf128.130d012b.js"><link rel="prefetch" href="/assets/js/page--1c48eaa8.9a689e30.js"><link rel="prefetch" href="/assets/js/page--1d4dfe96.bd551921.js"><link rel="prefetch" href="/assets/js/page--1dccf870.03d7d9cc.js"><link rel="prefetch" href="/assets/js/page--2074d3c8.06bf5706.js"><link rel="prefetch" href="/assets/js/page--22213c96.e703257a.js"><link rel="prefetch" href="/assets/js/page--2284eb70.514124de.js"><link rel="prefetch" href="/assets/js/page--22d0cd48.11ea1522.js"><link rel="prefetch" href="/assets/js/page--252cc6c8.f9acae83.js"><link rel="prefetch" href="/assets/js/page--2624cab0.4535fea2.js"><link rel="prefetch" href="/assets/js/page--269ff8f9.012e8ae6.js"><link rel="prefetch" href="/assets/js/page--26fcb668.35b2da5d.js"><link rel="prefetch" href="/assets/js/page--2958afe8.216913bc.js"><link rel="prefetch" href="/assets/js/page--2adcbdb0.6dcb4c27.js"><link rel="prefetch" href="/assets/js/page--2bb4a968.aac31797.js"><link rel="prefetch" href="/assets/js/page--2d849908.7bb4e817.js"><link rel="prefetch" href="/assets/js/page--2e10a2e8.42bef48d.js"><link rel="prefetch" href="/assets/js/page--2f94b0b0.0c993df5.js"><link rel="prefetch" href="/assets/js/page--2fe09288.77769dcb.js"><link rel="prefetch" href="/assets/js/page--323c8c08.254a5f78.js"><link rel="prefetch" href="/assets/js/page--33348ff0.a5f99eb0.js"><link rel="prefetch" href="/assets/js/page--340c7ba8.2c9570cb.js"><link rel="prefetch" href="/assets/js/page--34988588.8c8d0363.js"><link rel="prefetch" href="/assets/js/page--36687528.67d84e0d.js"><link rel="prefetch" href="/assets/js/page--37d6dfd6.88e9cd42.js"><link rel="prefetch" href="/assets/js/page--37ec82f0.5419c82d.js"><link rel="prefetch" href="/assets/js/page--37f7cf15.65f72e55.js"><link rel="prefetch" href="/assets/js/page--38c46ea8.5d5150f9.js"><link rel="prefetch" href="/assets/js/page--3a945e48.bf9758fb.js"><link rel="prefetch" href="/assets/js/page--3ab2204c.e08d6316.js"><link rel="prefetch" href="/assets/js/page--3b206828.d83e3926.js"><link rel="prefetch" href="/assets/js/page--3ca475f0.49e5acce.js"><link rel="prefetch" href="/assets/js/page--3cf057c8.8364331d.js"><link rel="prefetch" href="/assets/js/page--3f4c5148.587a8360.js"><link rel="prefetch" href="/assets/js/page--40445530.486bb516.js"><link rel="prefetch" href="/assets/js/page--411c40e8.2eedba0e.js"><link rel="prefetch" href="/assets/js/page--41a84ac8.f4a360a3.js"><link rel="prefetch" href="/assets/js/page--4220f8b5.19b4371f.js"><link rel="prefetch" href="/assets/js/page--43783a68.4faf0866.js"><link rel="prefetch" href="/assets/js/page--44fc4830.a160662c.js"><link rel="prefetch" href="/assets/js/page--45d433e8.560fef87.js"><link rel="prefetch" href="/assets/js/page--47a42388.052314b4.js"><link rel="prefetch" href="/assets/js/page--47d07816.66731286.js"><link rel="prefetch" href="/assets/js/page--48302d68.8d6493cf.js"><link rel="prefetch" href="/assets/js/page--49b43b30.e3684736.js"><link rel="prefetch" href="/assets/js/page--4a001d08.47f7ec45.js"><link rel="prefetch" href="/assets/js/page--4c5c1688.b7ec1f32.js"><link rel="prefetch" href="/assets/js/page--4d541a70.ee807705.js"><link rel="prefetch" href="/assets/js/page--4e2c0628.4f7105a4.js"><link rel="prefetch" href="/assets/js/page--4eb81008.725d26fe.js"><link rel="prefetch" href="/assets/js/page--5087ffa8.dac2aae0.js"><link rel="prefetch" href="/assets/js/page--520c0d70.2beedefb.js"><link rel="prefetch" href="/assets/js/page--52e3f928.2645087c.js"><link rel="prefetch" href="/assets/js/page--53cd0b44.96d4a285.js"><link rel="prefetch" href="/assets/js/page--54eb2c5e.27eb702b.js"><link rel="prefetch" href="/assets/js/page--553ff2a8.fba8ee4f.js"><link rel="prefetch" href="/assets/js/page--5686ab01.547b633c.js"><link rel="prefetch" href="/assets/js/page--56c40070.4e35708a.js"><link rel="prefetch" href="/assets/js/page--570fe248.2b301b36.js"><link rel="prefetch" href="/assets/js/page--596bdbc8.c74cd724.js"><link rel="prefetch" href="/assets/js/page--5a63dfb0.bbd49a9b.js"><link rel="prefetch" href="/assets/js/page--5bc7d548.eda26865.js"><link rel="prefetch" href="/assets/js/page--5f1bd2b0.e02cf88d.js"><link rel="prefetch" href="/assets/js/page--5ff3be68.b2b0e76e.js"><link rel="prefetch" href="/assets/js/page--624fb7e8.666fdc84.js"><link rel="prefetch" href="/assets/js/page--63d3c5b0.b587d38f.js"><link rel="prefetch" href="/assets/js/page--68d79a88.86f62e4d.js"><link rel="prefetch" href="/assets/js/page--6c2b97f0.ed46abea.js"><link rel="prefetch" href="/assets/js/page--6cc6a596.b3827451.js"><link rel="prefetch" href="/assets/js/page--6ea7a148.61a9bc10.js"><link rel="prefetch" href="/assets/js/page--70e38af0.eb8ffc53.js"><link rel="prefetch" href="/assets/js/page--7180d470.73a3a20e.js"><link rel="prefetch" href="/assets/js/page--752f83e8.d5c31640.js"><link rel="prefetch" href="/assets/js/page--778b7d68.5e8e5ea9.js"><link rel="prefetch" href="/assets/js/page--7bb76688.53e305e3.js"><link rel="prefetch" href="/assets/js/page--7c59a86a.ecf88c30.js"><link rel="prefetch" href="/assets/js/page--7df35030.cfa388f4.js"><link rel="prefetch" href="/assets/js/page--7e136008.230e9a15.js"><link rel="prefetch" href="/assets/js/page--89935db0.f79f9e25.js"><link rel="prefetch" href="/assets/js/page--96a322f0.412d537f.js"><link rel="prefetch" href="/assets/js/page--9b5b15f0.a5231547.js"><link rel="prefetch" href="/assets/js/page--a3b2e830.f4ba68fa.js"><link rel="prefetch" href="/assets/js/page--a86adb30.ec08486b.js"><link rel="prefetch" href="/assets/js/page--ad22ce30.4872eca4.js"><link rel="prefetch" href="/assets/js/page--b0c2ad70.8637057e.js"><link rel="prefetch" href="/assets/js/page--b57aa070.43215f9e.js"><link rel="prefetch" href="/assets/js/page--bdd272b0.aff1d1a9.js"><link rel="prefetch" href="/assets/js/page--c28a65b0.978514c4.js"><link rel="prefetch" href="/assets/js/page--c606edca.49d3396e.js"><link rel="prefetch" href="/assets/js/page--c74258b0.f85195bc.js"><link rel="prefetch" href="/assets/js/page--cae237f0.8a976cc1.js"><link rel="prefetch" href="/assets/js/page--cf9a2af0.7ad20ea2.js"><link rel="prefetch" href="/assets/js/page--d4521df0.a0a74934.js"><link rel="prefetch" href="/assets/js/page--d7f1fd30.160f138a.js"><link rel="prefetch" href="/assets/js/page--dca9f030.9127ab28.js"><link rel="prefetch" href="/assets/js/page--e161e330.34876a6f.js"><link rel="prefetch" href="/assets/js/page--e4f35ef4.690d3ccb.js"><link rel="prefetch" href="/assets/js/page--e501c270.8dc088ee.js"><link rel="prefetch" href="/assets/js/page--e9b9b570.b94764ed.js"><link rel="prefetch" href="/assets/js/page--ea4e0a70.94492571.js"><link rel="prefetch" href="/assets/js/page--ee71a870.b9944792.js"><link rel="prefetch" href="/assets/js/page--f21187b0.d00a5788.js"><link rel="prefetch" href="/assets/js/page--f6c97ab0.ecb91d64.js"><link rel="prefetch" href="/assets/js/page--fb816db0.c1f07c37.js"><link rel="prefetch" href="/assets/js/page--fcf2f51e.71000d71.js"><link rel="prefetch" href="/assets/js/page--ff214cf0.aaa8b0fc.js"><link rel="prefetch" href="/assets/js/page-GN.2f20b55f.js"><link rel="prefetch" href="/assets/js/page-GNFrequentlyAskedQuestions.24e61c26.js"><link rel="prefetch" href="/assets/js/page-GNLanguageandOperation.35e22ff2.js"><link rel="prefetch" href="/assets/js/page-GNQuickStartguide.7cd8e521.js"><link rel="prefetch" href="/assets/js/page-GNReference.1d5d0c6c.js"><link rel="prefetch" href="/assets/js/page-GNSimpleBuildExample.2eb0b7eb.js"><link rel="prefetch" href="/assets/js/page-GNStyleGuide.8a407135.js"><link rel="prefetch" href="/assets/js/page-GNU汇编教程.d208e4d7.js"><link rel="prefetch" href="/assets/js/page-GNvimsyntaxplugin.58d1459e.js"><link rel="prefetch" href="/assets/js/page-GN快速入门.b708bb6a.js"><link rel="prefetch" href="/assets/js/page-Home.97282d71.js"><link rel="prefetch" href="/assets/js/page-HowGNhandlescross-compiling.6ca64957.js"><link rel="prefetch" href="/assets/js/page-Introduction.292088e0.js"><link rel="prefetch" href="/assets/js/page-ninja快速入门.92729e64.js"><link rel="prefetch" href="/assets/js/page-《孙子兵法》全文.402792c5.js"><link rel="prefetch" href="/assets/js/page-《论语》全文.85da0da0.js"><link rel="prefetch" href="/assets/js/page-《诗经》全文.99ebeb52.js"><link rel="prefetch" href="/assets/js/page-《道德经》全文.43627e4e.js"><link rel="prefetch" href="/assets/js/page-两个文档.eb8dd1b7.js"><link rel="prefetch" href="/assets/js/page-主流站点覆盖定期同步更新.1ad02178.js"><link rel="prefetch" href="/assets/js/page-手机版电脑版.b5e8dfea.js"><link rel="prefetch" href="/assets/js/page-捐助方式.6ca91d44.js"><link rel="prefetch" href="/assets/js/page-来源LiteOS和LiteOS-A内核图解.8fa16705.js"><link rel="prefetch" href="/assets/js/page-电脑版手机版.67a0b4a4.js"><link rel="prefetch" href="/assets/js/page-编程语言相关书籍.d9adf7cb.js"><link rel="prefetch" href="/assets/js/page-鸿蒙内核源码分析.bbb451c7.js"><link rel="prefetch" href="/assets/js/vendors~flowchart.46b2de48.js"><link rel="prefetch" href="/assets/js/vendors~mermaid.627fb4be.js"><link rel="prefetch" href="/assets/js/vendors~photo-swipe.cbde97f9.js"><link rel="prefetch" href="/assets/js/vendors~reveal.77b21b7e.js">
    <link rel="stylesheet" href="/assets/css/0.styles.087eb7d3.css">
  </head>
  <body>
    <div id="app" data-server-rendered="true"><div class="theme-container has-navbar has-sidebar has-anchor"><header class="navbar"><!----> <div class="content__navbar-start"></div> <button title="Sidebar Button" class="sidebar-button"><span class="icon"></span></button> <a href="/" class="home-link router-link-active"><!----> <!----> <span class="site-name can-hide">中俊为 | we harmonyos</span></a> <!----> <div class="content__navbar-center"></div> <div class="links"><button tabindex="-1" aria-hidden="true" class="color-button"><svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" class="skin-icon"><path d="M224 800c0 9.6 3.2 44.8 6.4 54.4 6.4 48-48 76.8-48 76.8s80 41.6 147.2 0 134.4-134.4
        38.4-195.2c-22.4-12.8-41.6-19.2-57.6-19.2C259.2 716.8 227.2 761.6 224 800zM560 675.2l-32
        51.2c-51.2 51.2-83.2 32-83.2 32 25.6 67.2 0 112-12.8 128 25.6 6.4 51.2 9.6 80 9.6 54.4 0
        102.4-9.6 150.4-32l0 0c3.2 0 3.2-3.2 3.2-3.2 22.4-16 12.8-35.2
        6.4-44.8-9.6-12.8-12.8-25.6-12.8-41.6 0-54.4 60.8-99.2 137.6-99.2 6.4 0 12.8 0 22.4
        0 12.8 0 38.4 9.6 48-25.6 0-3.2 0-3.2 3.2-6.4 0-3.2 3.2-6.4 3.2-6.4 6.4-16 6.4-16 6.4-19.2
        9.6-35.2 16-73.6 16-115.2 0-105.6-41.6-198.4-108.8-268.8C704 396.8 560 675.2 560 675.2zM224
        419.2c0-28.8 22.4-51.2 51.2-51.2 28.8 0 51.2 22.4 51.2 51.2 0 28.8-22.4 51.2-51.2 51.2C246.4
        470.4 224 448 224 419.2zM320 284.8c0-22.4 19.2-41.6 41.6-41.6 22.4 0 41.6 19.2 41.6 41.6 0
        22.4-19.2 41.6-41.6 41.6C339.2 326.4 320 307.2 320 284.8zM457.6 208c0-12.8 12.8-25.6 25.6-25.6
        12.8 0 25.6 12.8 25.6 25.6 0 12.8-12.8 25.6-25.6 25.6C470.4 233.6 457.6 220.8 457.6 208zM128
        505.6C128 592 153.6 672 201.6 736c28.8-60.8 112-60.8 124.8-60.8-16-51.2 16-99.2
        16-99.2l316.8-422.4c-48-19.2-99.2-32-150.4-32C297.6 118.4 128 291.2 128 505.6zM764.8
        86.4c-22.4 19.2-390.4 518.4-390.4 518.4-22.4 28.8-12.8 76.8 22.4 99.2l9.6 6.4c35.2 22.4
        80 12.8 99.2-25.6 0 0 6.4-12.8 9.6-19.2 54.4-105.6 275.2-524.8 288-553.6
        6.4-19.2-3.2-32-19.2-32C777.6 76.8 771.2 80 764.8 86.4z"></path></svg> <div class="color-picker-menu" style="display:none;"><div class="theme-options"><ul class="themecolor-select"><label for="themecolor-select">Theme Color:</label> <li><span class="default-theme"></span></li> </ul> <div class="darkmode-toggle"><label for="darkmode-toggle" class="desc">Theme Mode:</label> <div class="darkmode-switch"><div class="item day"><svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" class="icon light-icon"><path d="M512 256a42.667 42.667 0 0 0 42.667-42.667V128a42.667 42.667 0 0 0-85.334 0v85.333A42.667 42.667 0 0 0 512 256zm384 213.333h-85.333a42.667 42.667 0 0 0 0 85.334H896a42.667 42.667 0 0 0 0-85.334zM256 512a42.667 42.667 0 0 0-42.667-42.667H128a42.667 42.667 0 0 0 0 85.334h85.333A42.667 42.667 0 0 0 256 512zm9.387-298.667a42.667 42.667 0 0 0-59.307 62.72l61.44 59.307a42.667 42.667 0 0 0 31.147 11.947 42.667 42.667 0 0 0 30.72-13.227 42.667 42.667 0 0 0 0-60.16zm459.946 133.974a42.667 42.667 0 0 0 29.44-11.947l61.44-59.307a42.667 42.667 0 0 0-57.6-62.72l-61.44 60.587a42.667 42.667 0 0 0 0 60.16 42.667 42.667 0 0 0 28.16 13.227zM512 768a42.667 42.667 0 0 0-42.667 42.667V896a42.667 42.667 0 0 0 85.334 0v-85.333A42.667 42.667 0 0 0 512 768zm244.48-79.36a42.667 42.667 0 0 0-59.307 61.44l61.44 60.587a42.667 42.667 0 0 0 29.44 11.946 42.667 42.667 0 0 0 30.72-12.8 42.667 42.667 0 0 0 0-60.586zm-488.96 0-61.44 59.307a42.667 42.667 0 0 0 0 60.586 42.667 42.667 0 0 0 30.72 12.8 42.667 42.667 0 0 0 28.587-10.666l61.44-59.307a42.667 42.667 0 0 0-59.307-61.44zM512 341.333A170.667 170.667 0 1 0 682.667 512 170.667 170.667 0 0 0 512 341.333z" fill="currentColor"></path></svg></div> <div class="item auto active"><svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" class="icon auto-icon"><path d="M460.864 539.072H564.8L510.592 376l-49.728 163.072zM872 362.368V149.504H659.648L510.528 0l-149.12 149.504H149.12v212.928L0 511.872l149.12 149.504v212.928h212.352l149.12 149.504 149.12-149.504h212.352V661.376l149.12-149.504L872 362.368zM614.464 693.12l-31.616-90.624H438.272l-31.616 90.624h-85.888l144.576-407.68h90.368l144.576 407.68h-85.824zm0 0" fill="currentColor"></path></svg></div> <div class="item night"><svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" class="icon dark-icon"><path d="M935.539 630.402c-11.43-11.432-28.674-14.739-43.531-8.354-46.734 20.103-96.363 30.297-147.508 30.297-99.59 0-193.221-38.784-263.64-109.203-108.637-108.637-139.61-270.022-78.908-411.148a39.497 39.497 0 0 0-51.886-51.887c-52.637 22.64-100.017 54.81-140.826 95.616-85.346 85.346-132.346 198.821-132.346 319.52 0 120.7 47.001 234.172 132.347 319.519S408.063 947.11 528.76 947.11c120.7 0 234.172-47.003 319.52-132.351 40.809-40.81 72.978-88.19 95.616-140.826a39.497 39.497 0 0 0-8.356-43.532z" fill="currentColor"></path></svg></div></div> <!----></div></div></div></button> <div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="/" class="nav-link router-link-active"><!---->
  首页
</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="文档中心" class="dropdown-title"><span class="title"><!---->
        文档中心
      </span> <span class="arrow"></span></button> <ul class="nav-dropdown"><li class="dropdown-item"><a href="http://open.weharmonyos.com/zh-cn/readme/Readme-CN.html" target="_blank" rel="noopener noreferrer" class="nav-link external"><!---->
  子系统
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><a href="http://open.weharmonyos.com/zh-cn/device-dev/website.html" target="_blank" rel="noopener noreferrer" class="nav-link external"><!---->
  南向
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><a href="http://open.weharmonyos.com/zh-cn/application-dev/website.html" target="_blank" rel="noopener noreferrer" class="nav-link external"><!---->
  北向
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="博客中心" class="dropdown-title"><span class="title"><!---->
        博客中心
      </span> <span class="arrow"></span></button> <ul class="nav-dropdown"><li class="dropdown-item"><a href="/blog/101.html" class="nav-link"><!---->
  总目录
</a></li><li class="dropdown-item"><a href="/blog/index/1_base.html" class="nav-link"><!---->
  基础知识
</a></li><li class="dropdown-item"><a href="/blog/index/2_process.html" class="nav-link"><!---->
  进程管理
</a></li><li class="dropdown-item"><a href="/blog/index/3_task.html" class="nav-link"><!---->
  任务管理
</a></li><li class="dropdown-item"><a href="/blog/index/4_mem.html" class="nav-link"><!---->
  内存管理
</a></li><li class="dropdown-item"><a href="/blog/index/5_ipc.html" class="nav-link"><!---->
  进程通讯
</a></li><li class="dropdown-item"><a href="/blog/index/6_fs.html" class="nav-link"><!---->
  文件系统
</a></li><li class="dropdown-item"><a href="/blog/index/7_hw.html" class="nav-link"><!---->
  软硬接口
</a></li><li class="dropdown-item"><a href="/blog/index/8_asm.html" class="nav-link"><!---->
  内核汇编
</a></li><li class="dropdown-item"><a href="/blog/index/9_run.html" class="nav-link"><!---->
  编译运行
</a></li><li class="dropdown-item"><a href="/blog/index/10_test.html" class="nav-link"><!---->
  调测工具
</a></li><li class="dropdown-item"><a href="/blog/index/0_so.html" class="nav-link"><!---->
  前因后果
</a></li><li class="dropdown-item"><a href="/extsite.html" class="nav-link"><!---->
  前往 &gt;&gt; 外站
</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="论坛中心" class="dropdown-title"><span class="title"><!---->
        论坛中心
      </span> <span class="arrow"></span></button> <ul class="nav-dropdown"><li class="dropdown-item"><a href="http://bbs.weharmonyos.com" target="_blank" rel="noopener noreferrer" class="nav-link external"><!---->
  论坛首页
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><a href="http://bbs.weharmonyos.com/forum-42-1.html" target="_blank" rel="noopener noreferrer" class="nav-link external"><!---->
  问题建议
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="手册中心" class="dropdown-title"><span class="title"><!---->
        手册中心
      </span> <span class="arrow"></span></button> <ul class="nav-dropdown"><li class="dropdown-item"><a href="http://doxygen.weharmonyos.com/index.html" target="_blank" rel="noopener noreferrer" class="nav-link external"><!---->
  内核参考手册
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><a href="/compile/assembly.html" class="nav-link"><!---->
  gnu 汇编教程
</a></li><li class="dropdown-item"><a href="/compile/gn/docs/" class="nav-link"><!---->
  gn 参考手册
</a></li><li class="dropdown-item"><a href="/compile/ninja/Readme-CN.html" class="nav-link"><!---->
  ninja 参考手册
</a></li><li class="dropdown-item"><a href="/compile/fhs.html" class="nav-link"><!---->
  fhs 规范
</a></li></ul></div></div><div class="nav-item"><a href="/donate.html" class="nav-link"><!---->
  赞助中心
</a></div></nav> <!----> <!----> <!----> <div class="content__navbar-end"></div></div></header> <div class="sidebar-mask"></div> <aside class="sidebar"><!----> <!----> <div class="content__sidebar-top"></div> <nav class="sidebar-nav-links"><div class="nav-item"><a href="/" class="nav-link router-link-active"><!---->
  首页
</a></div><div class="nav-item"><div class="mobile-dropdown-wrapper"><button type="button" aria-label="文档中心" class="dropdown-title"><span class="title"><!---->
      文档中心
    </span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="http://open.weharmonyos.com/zh-cn/readme/Readme-CN.html" target="_blank" rel="noopener noreferrer" class="nav-link external"><!---->
  子系统
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><!----> <a href="http://open.weharmonyos.com/zh-cn/device-dev/website.html" target="_blank" rel="noopener noreferrer" class="nav-link external"><!---->
  南向
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><!----> <a href="http://open.weharmonyos.com/zh-cn/application-dev/website.html" target="_blank" rel="noopener noreferrer" class="nav-link external"><!---->
  北向
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></div></div><div class="nav-item"><div class="mobile-dropdown-wrapper"><button type="button" aria-label="博客中心" class="dropdown-title"><span class="title"><!---->
      博客中心
    </span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/blog/101.html" class="nav-link"><!---->
  总目录
</a></li><li class="dropdown-item"><!----> <a href="/blog/index/1_base.html" class="nav-link"><!---->
  基础知识
</a></li><li class="dropdown-item"><!----> <a href="/blog/index/2_process.html" class="nav-link"><!---->
  进程管理
</a></li><li class="dropdown-item"><!----> <a href="/blog/index/3_task.html" class="nav-link"><!---->
  任务管理
</a></li><li class="dropdown-item"><!----> <a href="/blog/index/4_mem.html" class="nav-link"><!---->
  内存管理
</a></li><li class="dropdown-item"><!----> <a href="/blog/index/5_ipc.html" class="nav-link"><!---->
  进程通讯
</a></li><li class="dropdown-item"><!----> <a href="/blog/index/6_fs.html" class="nav-link"><!---->
  文件系统
</a></li><li class="dropdown-item"><!----> <a href="/blog/index/7_hw.html" class="nav-link"><!---->
  软硬接口
</a></li><li class="dropdown-item"><!----> <a href="/blog/index/8_asm.html" class="nav-link"><!---->
  内核汇编
</a></li><li class="dropdown-item"><!----> <a href="/blog/index/9_run.html" class="nav-link"><!---->
  编译运行
</a></li><li class="dropdown-item"><!----> <a href="/blog/index/10_test.html" class="nav-link"><!---->
  调测工具
</a></li><li class="dropdown-item"><!----> <a href="/blog/index/0_so.html" class="nav-link"><!---->
  前因后果
</a></li><li class="dropdown-item"><!----> <a href="/extsite.html" class="nav-link"><!---->
  前往 &gt;&gt; 外站
</a></li></ul></div></div><div class="nav-item"><div class="mobile-dropdown-wrapper"><button type="button" aria-label="论坛中心" class="dropdown-title"><span class="title"><!---->
      论坛中心
    </span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="http://bbs.weharmonyos.com" target="_blank" rel="noopener noreferrer" class="nav-link external"><!---->
  论坛首页
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><!----> <a href="http://bbs.weharmonyos.com/forum-42-1.html" target="_blank" rel="noopener noreferrer" class="nav-link external"><!---->
  问题建议
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></div></div><div class="nav-item"><div class="mobile-dropdown-wrapper"><button type="button" aria-label="手册中心" class="dropdown-title"><span class="title"><!---->
      手册中心
    </span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="http://doxygen.weharmonyos.com/index.html" target="_blank" rel="noopener noreferrer" class="nav-link external"><!---->
  内核参考手册
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><!----> <a href="/compile/assembly.html" class="nav-link"><!---->
  gnu 汇编教程
</a></li><li class="dropdown-item"><!----> <a href="/compile/gn/docs/" class="nav-link"><!---->
  gn 参考手册
</a></li><li class="dropdown-item"><!----> <a href="/compile/ninja/Readme-CN.html" class="nav-link"><!---->
  ninja 参考手册
</a></li><li class="dropdown-item"><!----> <a href="/compile/fhs.html" class="nav-link"><!---->
  fhs 规范
</a></li></ul></div></div><div class="nav-item"><a href="/donate.html" class="nav-link"><!---->
  赞助中心
</a></div> <!----></nav> <!----> <div class="content__sidebar-center"></div> <ul class="sidebar-links"><li><a href="/blog/101.html" class="sidebar-link">总目录</a></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading clickable"><!----> <span class="title">基础知识 | 10</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading clickable open"><!----> <span class="title">进程管理 | 10</span> <span class="arrow down"></span></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/blog/index/2_process.html" class="sidebar-link">本章目录</a></li><li><a href="/blog/11.html" class="sidebar-link">调度故事</a></li><li><a href="/blog/12.html" class="sidebar-link">进程控制块</a></li><li><a href="/blog/13.html" class="sidebar-link">进程空间</a></li><li><a href="/blog/14.html" class="sidebar-link">映射区</a></li><li><a href="/blog/15.html" class="sidebar-link">红黑树</a></li><li><a href="/blog/16.html" class="sidebar-link">进程管理</a></li><li><a href="/blog/17.html" aria-current="page" class="active sidebar-link">Fork进程</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/blog/18.html" class="sidebar-link">进程回收</a></li><li><a href="/blog/19.html" class="sidebar-link">Shell编辑</a></li><li><a href="/blog/20.html" class="sidebar-link">Shell解析</a></li></ul></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading clickable"><!----> <span class="title">任务管理 | 10</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading clickable"><!----> <span class="title">内存管理 | 10</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading clickable"><!----> <span class="title">通讯机制 | 14</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading clickable"><!----> <span class="title">文件系统 | 10</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading clickable"><!----> <span class="title">硬件架构 | 9</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading clickable"><!----> <span class="title">内核汇编 | 10</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading clickable"><!----> <span class="title">编译运行 | 13</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading clickable"><!----> <span class="title">调测工具 | 4</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading clickable"><!----> <span class="title">前因后果 | 4</span> <span class="arrow right"></span></p> <!----></section></li></ul> <!----> <div class="content__sidebar-bottom"></div> <!----></aside> <main class="page"><nav class="breadcrumb disable"><!----></nav> <!----> <div class="content__page-top"></div> <div vocab="https://schema.org/" typeof="Article" class="page-title"><h1><!----> <span property="headline"></span></h1> <div class="page-info"><!----> </div> <!----> <hr></div> <div class="anchor-place-holder"><aside id="anchor"><div class="anchor-wrapper"><ul class="anchor-list"><li class="anchor"><a href="/blog/17.html#fork是什么" class="anchor-link heading3"><div>fork是什么</div></a></li><li class="anchor"><a href="/blog/17.html#运行结果" class="anchor-link heading3"><div>运行结果</div></a></li><li class="anchor"><a href="/blog/17.html#为什么是fork" class="anchor-link heading3"><div>为什么是fork</div></a></li><li class="anchor"><a href="/blog/17.html#fork怎么实现的" class="anchor-link heading3"><div>fork怎么实现的？</div></a></li><li class="anchor"><a href="/blog/17.html#百文说内核-抓住主脉络" class="anchor-link heading3"><div>百文说内核 | 抓住主脉络</div></a></li><li class="anchor"><a href="/blog/17.html#百万注源码-处处扣细节" class="anchor-link heading3"><div>百万注源码 | 处处扣细节</div></a></li><li class="anchor"><a href="/blog/17.html#关注不迷路-代码即人生" class="anchor-link heading3"><div>关注不迷路 | 代码即人生</div></a></li></ul></div></aside></div> <!----> <div class="content__content-top"></div> <div class="theme-default-content content__default"><p>本篇关键词：、、、</p> <p><a href="https://weharmony.gitee.io/blog/17.html" target="_blank" rel="noopener noreferrer"><img src="https://weharmonyos.oss-cn-hangzhou.aliyuncs.com/resources/index/17.png" alt=""></a></p> <p><a href="https://weharmonyos.oss-cn-hangzhou.aliyuncs.com/resources/pdf/%E9%B8%BF%E8%92%99%E5%86%85%E6%A0%B8%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90(%E7%99%BE%E7%AF%87%E5%8D%9A%E5%AE%A2%E5%88%86%E6%9E%90.%E6%8C%96%E9%80%8F%E9%B8%BF%E8%92%99%E5%86%85%E6%A0%B8).zip" target="_blank" rel="noopener noreferrer">下载 &gt;&gt; 离线文档.鸿蒙内核源码分析(百篇博客分析.挖透鸿蒙内核).pdf</a></p> <p>进程管理相关篇为:</p> <ul><li><a href="http://weharmonyos.com/blog/11.html" target="_blank" rel="noopener noreferrer">v11.04 鸿蒙内核源码分析(调度故事) | 大郎，该喝药了</a></li> <li><a href="http://weharmonyos.com/blog/12.html" target="_blank" rel="noopener noreferrer">v12.03 鸿蒙内核源码分析(进程控制块) | 可怜天下父母心</a></li> <li><a href="http://weharmonyos.com/blog/13.html" target="_blank" rel="noopener noreferrer">v13.01 鸿蒙内核源码分析(进程空间) | 有爱的地方才叫家 </a></li> <li><a href="http://weharmonyos.com/blog/14.html" target="_blank" rel="noopener noreferrer">v14.01 鸿蒙内核源码分析(线性区) | 人要有空间才能好好相处</a></li> <li><a href="http://weharmonyos.com/blog/15.html" target="_blank" rel="noopener noreferrer">v15.01 鸿蒙内核源码分析(红黑树) | 众里寻他千百度 </a></li> <li><a href="http://weharmonyos.com/blog/16.html" target="_blank" rel="noopener noreferrer">v16.06 鸿蒙内核源码分析(进程管理) | 家家有本难念的经</a></li> <li><a href="http://weharmonyos.com/blog/17.html" target="_blank" rel="noopener noreferrer">v17.05 鸿蒙内核源码分析(Fork进程) | 一次调用 两次返回</a></li> <li><a href="http://weharmonyos.com/blog/18.html" target="_blank" rel="noopener noreferrer">v18.02 鸿蒙内核源码分析(进程回收) | 临终托孤的短命娃</a></li> <li><a href="http://weharmonyos.com/blog/19.html" target="_blank" rel="noopener noreferrer">v19.03 鸿蒙内核源码分析(Shell编辑) | 两个任务 三个阶段</a></li> <li><a href="http://weharmonyos.com/blog/20.html" target="_blank" rel="noopener noreferrer">v20.01 鸿蒙内核源码分析(Shell解析) | 应用窥伺内核的窗口</a></li></ul> <p>笔者第一次看到fork时，说是一次调用，两次返回，当时就懵圈了，多新鲜，真的很难理解。因为这足以颠覆了以往对函数的认知， 函数调用还能这么玩，父进程调用一次，父子进程各返回一次。而且只能通过返回值来判断是哪个进程的返回。所以一直有几个问题缠绕在脑海中。</p> <ul><li>fork是什么？ 外部如何正确使用它。</li> <li>为什么要用fork这种设计？ fork的本质和好处是什么？</li> <li>怎么做到的？ 调用fork()使得父子进程各返回一次，怎么做到返回两次的，其中到底发生了什么？</li> <li>为什么<code>pid = 0</code> 代表了是子进程的返回？ 为什么父进程不需要返回 0 ？</li></ul> <p>直到看了linux内核源码后才搞明白，但系列篇的定位是挖透鸿蒙的内核源码，所以本篇将深入fork函数，用鸿蒙内核源码去说明白这些问题。在看本篇之前建议要先看系列篇的其他篇幅。如(任务切换篇，寄存器篇，工作模式篇，系统调用篇 等)，有了这些基础，会很好理解fork的实现过程。</p> <h3 id="fork是什么">fork是什么</h3> <p>先看一个网上经常拿来说fork的一个代码片段。</p> <div class="language-c line-numbers-mode"><pre class="language-c"><code><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;sys/types.h&gt;</span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;unistd.h&gt;</span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;stdio.h&gt;</span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;stdlib.h&gt;</span></span>

<span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
	<span class="token class-name">pid_t</span> pid<span class="token punctuation">;</span>
	<span class="token keyword">char</span> <span class="token operator">*</span>message<span class="token punctuation">;</span>
	<span class="token keyword">int</span> n<span class="token punctuation">;</span>
	pid <span class="token operator">=</span> <span class="token function">fork</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token keyword">if</span> <span class="token punctuation">(</span>pid <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
		<span class="token function">perror</span><span class="token punctuation">(</span><span class="token string">&quot;fork failed&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
		<span class="token function">exit</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token punctuation">}</span>
	<span class="token keyword">if</span> <span class="token punctuation">(</span>pid <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
		message <span class="token operator">=</span> <span class="token string">&quot;This is the child\n&quot;</span><span class="token punctuation">;</span>
		n <span class="token operator">=</span> <span class="token number">6</span><span class="token punctuation">;</span>
	<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
		message <span class="token operator">=</span> <span class="token string">&quot;This is the parent\n&quot;</span><span class="token punctuation">;</span>
		n <span class="token operator">=</span> <span class="token number">3</span><span class="token punctuation">;</span>
	<span class="token punctuation">}</span>
	<span class="token keyword">for</span><span class="token punctuation">(</span><span class="token punctuation">;</span> n <span class="token operator">&gt;</span> <span class="token number">0</span><span class="token punctuation">;</span> n<span class="token operator">--</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
		<span class="token function">printf</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span>
		<span class="token function">sleep</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token punctuation">}</span>
	<span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br></div></div><ul><li><code>pid &lt; 0</code>  fork 失败</li> <li><code>pid == 0</code> fork成功，是子进程的返回</li> <li><code>pid &gt; 0</code>  fork成功，是父进程的返回</li> <li><code>fork</code>的返回值这样规定是有道理的。<code>fork</code>在子进程中返回0，子进程仍可以调用<code>getpid</code>函数得到自己的进程id，也可以调用<code>getppid</code>函数得到父进程的id。在父进程中用<code>getpid</code>可以得到自己的进程id，然而要想得到子进程的id，只有将<code>fork</code>的返回值记录下来，别无它法。</li> <li>子进程并没有真正执行<code>fork()</code>，而是内核用了一个很巧妙的方法获得了返回值，并且将返回值硬生生的改写成了0，这是笔者认为<code>fork</code>的实现最精彩的部分。</li></ul> <h3 id="运行结果">运行结果</h3> <div class="language-c line-numbers-mode"><pre class="language-c"><code>$ <span class="token punctuation">.</span><span class="token operator">/</span>a<span class="token punctuation">.</span>out 
This is the child
This is the parent
This is the child
This is the parent
This is the child
This is the parent
This is the child
$ This is the child
This is the child
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br></div></div><p>这个程序的运行过程如下图所示。
<img src="https://weharmonyos.oss-cn-hangzhou.aliyuncs.com/resources/45/process_fork.png" alt=""></p> <p><strong>解读</strong></p> <ul><li><p><code>fork()</code> 是一个系统调用，因此会切换到SVC模式运行。在SVC栈中父进程复制出一个子进程，父进程和子进程的PCB信息相同，用户态代码和数据也相同。</p></li> <li><p>从案例的执行上可以看出，fork 之后的代码父子进程都会执行，即代码段指向(PC寄存器)是一样的。实际上fork只被父进程调用了一次，子进程并没有执行<code>fork</code>函数，但是却获得了一个返回值，<code>pid == 0</code>，这个非常重要。这是本篇说明的重点。</p></li> <li><p>从执行结果上看，父进程打印了三次(This is the parent)，因为 n = 3。  子进程打印了六次(This is the child)，因为 n = 6。 而子程序并没有执行以下代码:</p> <div class="language-c line-numbers-mode"><pre class="language-c"><code>    <span class="token class-name">pid_t</span> pid<span class="token punctuation">;</span>
    <span class="token keyword">char</span> <span class="token operator">*</span>message<span class="token punctuation">;</span>
    <span class="token keyword">int</span> n<span class="token punctuation">;</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><p>子进程是从<code>pid = fork()</code> 后开始执行的，按理它不会在新任务栈中出现这些变量，而实际上后面又能顺利的使用这些变量，说明父进程当前任务的用户态的数据也复制了一份给子进程的新任务栈中。</p></li> <li><p>被fork成功的子进程跑的首条代码指令是 <code>pid = 0</code>，这里的0是返回值，存放在<code>R0</code>寄存器中。说明父进程的任务上下文也进行了一次拷贝，父进程从内核态回到用户态时恢复的上下文和子进程的任务上下文是一样的，即 PC寄存器指向是一样的，如此才能确保在代码段相同的位置执行。</p></li> <li><p>执行<code>./a.out</code>后 第一条打印的是<code>This is the child</code>说明 <code>fork()</code>中发生了一次调度，CPU切到了子进程的任务执行，<code>sleep(1)</code>的本质在系列篇中多次说过是任务主动放弃CPU的使用权，将自己挂入任务等待链表，由此发生一次任务调度，CPU切到父进程执行，才有了打印第二条的<code>This is the parent</code>，父进程的<code>sleep(1)</code>又切到子进程如此往返，直到 n = 0， 结束父子进程。</p></li> <li><p>但这个例子和笔者的解读只解释了fork是什么的使用说明书，并猜测其中做了些什么，并没有说明为什么要这样做和代码是怎么实现的。 正式结合鸿蒙的源码说清楚为什么和怎么做这两个问题？</p></li></ul> <h3 id="为什么是fork">为什么是fork</h3> <p>fork函数的特点概括起来就是“调用一次，返回两次”，在父进程中调用一次，在父进程和子进程中各返回一次。从上图可以看出，一开始是一个控制流程，调用fork之后发生了分叉，变成两个控制流程，这也就是“fork”（分叉）这个名字的由来了。
系列篇已经写了40+多篇，已经很容易理解一个程序运行起来就需要各种资源(内存，文件，ipc，监控信息等等)，资源就需要管理，进程就是管理资源的容器。这些资源相当于干活需要各种工具一样，干活的工具都差不多，实在没必再走流程一一申请，而且申请下来会发现和别人手里已有的工具都一样， 别人有直接拿过来使用它不香吗？ 所以最简单的办法就是认个干爹，让干爹拷贝一份干活工具给你。这样只需要专心的干好活(任务)就行了。 fork的本质就是copy，具体看代码。</p> <h3 id="fork怎么实现的">fork怎么实现的？</h3> <div class="language-c line-numbers-mode"><pre class="language-c"><code><span class="token comment">//系统调用之fork ，建议去 https://gitee.com/weharmony/kernel_liteos_a_note fork 一下？ :P </span>
<span class="token keyword">int</span> <span class="token function">SysFork</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token function">OsClone</span><span class="token punctuation">(</span>CLONE_SIGHAND， <span class="token number">0</span>， <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//本质就是克隆</span>
<span class="token punctuation">}</span>
LITE_OS_SEC_TEXT INT32 <span class="token function">OsClone</span><span class="token punctuation">(</span>UINT32 flags， UINTPTR sp， UINT32 size<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    UINT32 cloneFlag <span class="token operator">=</span> CLONE_PARENT <span class="token operator">|</span> CLONE_THREAD <span class="token operator">|</span> CLONE_VFORK <span class="token operator">|</span> CLONE_VM<span class="token punctuation">;</span>

    <span class="token keyword">if</span> <span class="token punctuation">(</span>flags <span class="token operator">&amp;</span> <span class="token punctuation">(</span><span class="token operator">~</span>cloneFlag<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token function">PRINT_WARN</span><span class="token punctuation">(</span><span class="token string">&quot;Clone dont support some flags!\n&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">return</span> <span class="token function">OsCopyProcess</span><span class="token punctuation">(</span>cloneFlag <span class="token operator">&amp;</span> flags， <span class="token constant">NULL</span>， sp， size<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
STATIC INT32 <span class="token function">OsCopyProcess</span><span class="token punctuation">(</span>UINT32 flags， <span class="token keyword">const</span> CHAR <span class="token operator">*</span>name， UINTPTR sp， UINT32 size<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    UINT32 intSave， ret， processID<span class="token punctuation">;</span>
    LosProcessCB <span class="token operator">*</span>run <span class="token operator">=</span> <span class="token function">OsCurrProcessGet</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//获取当前进程</span>

    LosProcessCB <span class="token operator">*</span>child <span class="token operator">=</span> <span class="token function">OsGetFreePCB</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//从进程池中申请一个进程控制块，鸿蒙进程池默认64</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>child <span class="token operator">==</span> <span class="token constant">NULL</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token operator">-</span>LOS_EAGAIN<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    processID <span class="token operator">=</span> child<span class="token operator">-&gt;</span>processID<span class="token punctuation">;</span>

    ret <span class="token operator">=</span> <span class="token function">OsForkInitPCB</span><span class="token punctuation">(</span>flags， child， name， sp， size<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//初始化进程控制块</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>ret <span class="token operator">!=</span> LOS_OK<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">goto</span> ERROR_INIT<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    ret <span class="token operator">=</span> <span class="token function">OsCopyProcessResources</span><span class="token punctuation">(</span>flags， child， run<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//拷贝进程的资源，包括虚拟空间，文件，安全，IPC ==</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>ret <span class="token operator">!=</span> LOS_OK<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">goto</span> ERROR_TASK<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    ret <span class="token operator">=</span> <span class="token function">OsChildSetProcessGroupAndSched</span><span class="token punctuation">(</span>child， run<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//设置进程组和加入进程调度就绪队列</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>ret <span class="token operator">!=</span> LOS_OK<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">goto</span> ERROR_TASK<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token function">LOS_MpSchedule</span><span class="token punctuation">(</span>OS_MP_CPU_ALL<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//给各CPU发送准备接受调度信号</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>OS_SCHEDULER_ACTIVE<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token comment">//当前CPU core处于活动状态</span>
        <span class="token function">LOS_Schedule</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// 申请调度</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">return</span> processID<span class="token punctuation">;</span>

ERROR_TASK<span class="token operator">:</span>
    <span class="token function">SCHEDULER_LOCK</span><span class="token punctuation">(</span>intSave<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">(</span>VOID<span class="token punctuation">)</span><span class="token function">OsTaskDeleteUnsafe</span><span class="token punctuation">(</span><span class="token function">OS_TCB_FROM_TID</span><span class="token punctuation">(</span>child<span class="token operator">-&gt;</span>threadGroupID<span class="token punctuation">)</span>， OS_PRO_EXIT_OK， intSave<span class="token punctuation">)</span><span class="token punctuation">;</span>
ERROR_INIT<span class="token operator">:</span>
    <span class="token function">OsDeInitPCB</span><span class="token punctuation">(</span>child<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> <span class="token operator">-</span>ret<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
### OsForkInitPCB
STATIC <span class="token function">UINT32</span> <span class="token punctuation">(</span>UINT32 flags， LosProcessCB <span class="token operator">*</span>child， <span class="token keyword">const</span> CHAR <span class="token operator">*</span>name， UINTPTR sp， UINT32 size<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    UINT32 ret<span class="token punctuation">;</span>
    LosProcessCB <span class="token operator">*</span>run <span class="token operator">=</span> <span class="token function">OsCurrProcessGet</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//获取当前进程</span>

    ret <span class="token operator">=</span> <span class="token function">OsInitPCB</span><span class="token punctuation">(</span>child， run<span class="token operator">-&gt;</span>processMode， OS_PROCESS_PRIORITY_LOWEST， LOS_SCHED_RR， name<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//初始化PCB信息，进程模式，优先级，调度方式，名称 == 信息</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>ret <span class="token operator">!=</span> LOS_OK<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> ret<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    ret <span class="token operator">=</span> <span class="token function">OsCopyParent</span><span class="token punctuation">(</span>flags， child， run<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//拷贝父亲大人的基因信息</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>ret <span class="token operator">!=</span> LOS_OK<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> ret<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">return</span> <span class="token function">OsCopyTask</span><span class="token punctuation">(</span>flags， child， name， sp， size<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//拷贝任务，设置任务入口函数，栈大小</span>
<span class="token punctuation">}</span>
<span class="token comment">//初始化PCB块</span>
STATIC UINT32 <span class="token function">OsInitPCB</span><span class="token punctuation">(</span>LosProcessCB <span class="token operator">*</span>processCB， UINT32 mode， UINT16 priority， UINT16 policy， <span class="token keyword">const</span> CHAR <span class="token operator">*</span>name<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    UINT32 count<span class="token punctuation">;</span>
    LosVmSpace <span class="token operator">*</span>space <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">;</span>
    LosVmPage <span class="token operator">*</span>vmPage <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">;</span>
    <span class="token class-name">status_t</span> status<span class="token punctuation">;</span>
    BOOL retVal <span class="token operator">=</span> FALSE<span class="token punctuation">;</span>

    processCB<span class="token operator">-&gt;</span>processMode <span class="token operator">=</span> mode<span class="token punctuation">;</span>						<span class="token comment">//用户态进程还是内核态进程</span>
    processCB<span class="token operator">-&gt;</span>processStatus <span class="token operator">=</span> OS_PROCESS_STATUS_INIT<span class="token punctuation">;</span>	<span class="token comment">//进程初始状态</span>
    processCB<span class="token operator">-&gt;</span>parentProcessID <span class="token operator">=</span> OS_INVALID_VALUE<span class="token punctuation">;</span>		<span class="token comment">//爸爸进程，外面指定</span>
    processCB<span class="token operator">-&gt;</span>threadGroupID <span class="token operator">=</span> OS_INVALID_VALUE<span class="token punctuation">;</span>		<span class="token comment">//所属线程组</span>
    processCB<span class="token operator">-&gt;</span>priority <span class="token operator">=</span> priority<span class="token punctuation">;</span>						<span class="token comment">//进程优先级</span>
    processCB<span class="token operator">-&gt;</span>policy <span class="token operator">=</span> policy<span class="token punctuation">;</span>							<span class="token comment">//调度算法 LOS_SCHED_RR</span>
    processCB<span class="token operator">-&gt;</span>umask <span class="token operator">=</span> OS_PROCESS_DEFAULT_UMASK<span class="token punctuation">;</span>		<span class="token comment">//掩码</span>
    processCB<span class="token operator">-&gt;</span>timerID <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token class-name">timer_t</span><span class="token punctuation">)</span><span class="token punctuation">(</span>UINTPTR<span class="token punctuation">)</span>MAX_INVALID_TIMER_VID<span class="token punctuation">;</span>

    <span class="token function">LOS_ListInit</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>processCB<span class="token operator">-&gt;</span>threadSiblingList<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//初始化孩子任务/线程链表，上面挂的都是由此fork的孩子线程 见于 OsTaskCBInit LOS_ListTailInsert(&amp;(processCB-&gt;threadSiblingList)， &amp;(taskCB-&gt;threadList));</span>
    <span class="token function">LOS_ListInit</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>processCB<span class="token operator">-&gt;</span>childrenList<span class="token punctuation">)</span><span class="token punctuation">;</span>		<span class="token comment">//初始化孩子进程链表，上面挂的都是由此fork的孩子进程 见于 OsCopyParent LOS_ListTailInsert(&amp;parentProcessCB-&gt;childrenList， &amp;childProcessCB-&gt;siblingList);</span>
    <span class="token function">LOS_ListInit</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>processCB<span class="token operator">-&gt;</span>exitChildList<span class="token punctuation">)</span><span class="token punctuation">;</span>	<span class="token comment">//初始化记录退出孩子进程链表，上面挂的是哪些exit	见于 OsProcessNaturalExit LOS_ListTailInsert(&amp;parentCB-&gt;exitChildList， &amp;processCB-&gt;siblingList);</span>
    <span class="token function">LOS_ListInit</span><span class="token punctuation">(</span><span class="token operator">&amp;</span><span class="token punctuation">(</span>processCB<span class="token operator">-&gt;</span>waitList<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>		<span class="token comment">//初始化等待任务链表 上面挂的是处于等待的 见于 OsWaitInsertWaitLIstInOrder LOS_ListHeadInsert(&amp;processCB-&gt;waitList， &amp;runTask-&gt;pendList);</span>

    <span class="token keyword">for</span> <span class="token punctuation">(</span>count <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> count <span class="token operator">&lt;</span> OS_PRIORITY_QUEUE_NUM<span class="token punctuation">;</span> <span class="token operator">++</span>count<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">//根据 priority数 创建对应个数的队列</span>
        <span class="token function">LOS_ListInit</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>processCB<span class="token operator">-&gt;</span>threadPriQueueList<span class="token punctuation">[</span>count<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//初始化一个个线程队列，队列中存放就绪状态的线程/task </span>
    <span class="token punctuation">}</span><span class="token comment">//在鸿蒙内核中 task就是thread，在鸿蒙源码分析系列篇中有详细阐释 见于 https://my.oschina.net/u/3751245</span>

    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">OsProcessIsUserMode</span><span class="token punctuation">(</span>processCB<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token comment">// 是否为用户模式进程</span>
        space <span class="token operator">=</span> <span class="token function">LOS_MemAlloc</span><span class="token punctuation">(</span>m_aucSysMem0， <span class="token keyword">sizeof</span><span class="token punctuation">(</span>LosVmSpace<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//分配一个虚拟空间</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>space <span class="token operator">==</span> <span class="token constant">NULL</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token function">PRINT_ERR</span><span class="token punctuation">(</span><span class="token string">&quot;%s %d， alloc space failed\n&quot;</span>， __FUNCTION__， <span class="token constant">__LINE__</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">return</span> LOS_ENOMEM<span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        VADDR_T <span class="token operator">*</span>ttb <span class="token operator">=</span> <span class="token function">LOS_PhysPagesAllocContiguous</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//分配一个物理页用于存储L1页表 4G虚拟内存分成 （4096*1M）</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>ttb <span class="token operator">==</span> <span class="token constant">NULL</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token comment">//这里直接获取物理页ttb</span>
            <span class="token function">PRINT_ERR</span><span class="token punctuation">(</span><span class="token string">&quot;%s %d， alloc ttb or space failed\n&quot;</span>， __FUNCTION__， <span class="token constant">__LINE__</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">(</span>VOID<span class="token punctuation">)</span><span class="token function">LOS_MemFree</span><span class="token punctuation">(</span>m_aucSysMem0， space<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">return</span> LOS_ENOMEM<span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        <span class="token punctuation">(</span>VOID<span class="token punctuation">)</span><span class="token function">memset_s</span><span class="token punctuation">(</span>ttb， PAGE_SIZE， <span class="token number">0</span>， PAGE_SIZE<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//内存清0</span>
        retVal <span class="token operator">=</span> <span class="token function">OsUserVmSpaceInit</span><span class="token punctuation">(</span>space， ttb<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//初始化虚拟空间和进程mmu</span>
        vmPage <span class="token operator">=</span> <span class="token function">OsVmVaddrToPage</span><span class="token punctuation">(</span>ttb<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//通过虚拟地址拿到page</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>retVal <span class="token operator">==</span> FALSE<span class="token punctuation">)</span> <span class="token operator">||</span> <span class="token punctuation">(</span>vmPage <span class="token operator">==</span> <span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token comment">//异常处理</span>
            <span class="token function">PRINT_ERR</span><span class="token punctuation">(</span><span class="token string">&quot;create space failed! ret: %d， vmPage: %#x\n&quot;</span>， retVal， vmPage<span class="token punctuation">)</span><span class="token punctuation">;</span>
            processCB<span class="token operator">-&gt;</span>processStatus <span class="token operator">=</span> OS_PROCESS_FLAG_UNUSED<span class="token punctuation">;</span><span class="token comment">//进程未使用，干净</span>
            <span class="token punctuation">(</span>VOID<span class="token punctuation">)</span><span class="token function">LOS_MemFree</span><span class="token punctuation">(</span>m_aucSysMem0， space<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//释放虚拟空间</span>
            <span class="token function">LOS_PhysPagesFreeContiguous</span><span class="token punctuation">(</span>ttb， <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//释放物理页，4K</span>
            <span class="token keyword">return</span> LOS_EAGAIN<span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        processCB<span class="token operator">-&gt;</span>vmSpace <span class="token operator">=</span> space<span class="token punctuation">;</span><span class="token comment">//设为进程虚拟空间</span>
        <span class="token function">LOS_ListAdd</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>processCB<span class="token operator">-&gt;</span>vmSpace<span class="token operator">-&gt;</span>archMmu<span class="token punctuation">.</span>ptList， <span class="token operator">&amp;</span><span class="token punctuation">(</span>vmPage<span class="token operator">-&gt;</span>node<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//将空间映射页表挂在 空间的mmu L1页表， L1为表头</span>
    <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
        processCB<span class="token operator">-&gt;</span>vmSpace <span class="token operator">=</span> <span class="token function">LOS_GetKVmSpace</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//内核共用一个虚拟空间，内核进程 常驻内存</span>
    <span class="token punctuation">}</span>

<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">ifdef</span> <span class="token expression">LOSCFG_SECURITY_VID</span></span>
    status <span class="token operator">=</span> <span class="token function">VidMapListInit</span><span class="token punctuation">(</span>processCB<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>status <span class="token operator">!=</span> LOS_OK<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token function">PRINT_ERR</span><span class="token punctuation">(</span><span class="token string">&quot;VidMapListInit failed!\n&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> LOS_ENOMEM<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">endif</span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">ifdef</span> <span class="token expression">LOSCFG_SECURITY_CAPABILITY</span></span>
    <span class="token function">OsInitCapability</span><span class="token punctuation">(</span>processCB<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">endif</span></span>

    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">OsSetProcessName</span><span class="token punctuation">(</span>processCB， name<span class="token punctuation">)</span> <span class="token operator">!=</span> LOS_OK<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> LOS_ENOMEM<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">return</span> LOS_OK<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br><span class="line-number">37</span><br><span class="line-number">38</span><br><span class="line-number">39</span><br><span class="line-number">40</span><br><span class="line-number">41</span><br><span class="line-number">42</span><br><span class="line-number">43</span><br><span class="line-number">44</span><br><span class="line-number">45</span><br><span class="line-number">46</span><br><span class="line-number">47</span><br><span class="line-number">48</span><br><span class="line-number">49</span><br><span class="line-number">50</span><br><span class="line-number">51</span><br><span class="line-number">52</span><br><span class="line-number">53</span><br><span class="line-number">54</span><br><span class="line-number">55</span><br><span class="line-number">56</span><br><span class="line-number">57</span><br><span class="line-number">58</span><br><span class="line-number">59</span><br><span class="line-number">60</span><br><span class="line-number">61</span><br><span class="line-number">62</span><br><span class="line-number">63</span><br><span class="line-number">64</span><br><span class="line-number">65</span><br><span class="line-number">66</span><br><span class="line-number">67</span><br><span class="line-number">68</span><br><span class="line-number">69</span><br><span class="line-number">70</span><br><span class="line-number">71</span><br><span class="line-number">72</span><br><span class="line-number">73</span><br><span class="line-number">74</span><br><span class="line-number">75</span><br><span class="line-number">76</span><br><span class="line-number">77</span><br><span class="line-number">78</span><br><span class="line-number">79</span><br><span class="line-number">80</span><br><span class="line-number">81</span><br><span class="line-number">82</span><br><span class="line-number">83</span><br><span class="line-number">84</span><br><span class="line-number">85</span><br><span class="line-number">86</span><br><span class="line-number">87</span><br><span class="line-number">88</span><br><span class="line-number">89</span><br><span class="line-number">90</span><br><span class="line-number">91</span><br><span class="line-number">92</span><br><span class="line-number">93</span><br><span class="line-number">94</span><br><span class="line-number">95</span><br><span class="line-number">96</span><br><span class="line-number">97</span><br><span class="line-number">98</span><br><span class="line-number">99</span><br><span class="line-number">100</span><br><span class="line-number">101</span><br><span class="line-number">102</span><br><span class="line-number">103</span><br><span class="line-number">104</span><br><span class="line-number">105</span><br><span class="line-number">106</span><br><span class="line-number">107</span><br><span class="line-number">108</span><br><span class="line-number">109</span><br><span class="line-number">110</span><br><span class="line-number">111</span><br><span class="line-number">112</span><br><span class="line-number">113</span><br><span class="line-number">114</span><br><span class="line-number">115</span><br><span class="line-number">116</span><br><span class="line-number">117</span><br><span class="line-number">118</span><br><span class="line-number">119</span><br><span class="line-number">120</span><br><span class="line-number">121</span><br><span class="line-number">122</span><br><span class="line-number">123</span><br><span class="line-number">124</span><br><span class="line-number">125</span><br><span class="line-number">126</span><br><span class="line-number">127</span><br><span class="line-number">128</span><br><span class="line-number">129</span><br><span class="line-number">130</span><br><span class="line-number">131</span><br><span class="line-number">132</span><br><span class="line-number">133</span><br><span class="line-number">134</span><br><span class="line-number">135</span><br><span class="line-number">136</span><br><span class="line-number">137</span><br><span class="line-number">138</span><br><span class="line-number">139</span><br><span class="line-number">140</span><br><span class="line-number">141</span><br><span class="line-number">142</span><br><span class="line-number">143</span><br><span class="line-number">144</span><br><span class="line-number">145</span><br></div></div><div class="language-c line-numbers-mode"><pre class="language-c"><code><span class="token comment">//拷贝一个Task过程</span>
STATIC UINT32 <span class="token function">OsCopyTask</span><span class="token punctuation">(</span>UINT32 flags， LosProcessCB <span class="token operator">*</span>childProcessCB， <span class="token keyword">const</span> CHAR <span class="token operator">*</span>name， UINTPTR entry， UINT32 size<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    LosTaskCB <span class="token operator">*</span>childTaskCB <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">;</span>
    TSK_INIT_PARAM_S childPara <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token number">0</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>
    UINT32 ret<span class="token punctuation">;</span>
    UINT32 intSave<span class="token punctuation">;</span>
    UINT32 taskID<span class="token punctuation">;</span>

    <span class="token function">OsInitCopyTaskParam</span><span class="token punctuation">(</span>childProcessCB， name， entry， size， <span class="token operator">&amp;</span>childPara<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//初始化Task参数</span>

    ret <span class="token operator">=</span> <span class="token function">LOS_TaskCreateOnly</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>taskID， <span class="token operator">&amp;</span>childPara<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//只创建任务，不调度</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>ret <span class="token operator">!=</span> LOS_OK<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>ret <span class="token operator">==</span> LOS_ERRNO_TSK_TCB_UNAVAILABLE<span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token keyword">return</span> LOS_EAGAIN<span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        <span class="token keyword">return</span> LOS_ENOMEM<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    childTaskCB <span class="token operator">=</span> <span class="token function">OS_TCB_FROM_TID</span><span class="token punctuation">(</span>taskID<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//通过taskId获取task实体</span>
    childTaskCB<span class="token operator">-&gt;</span>taskStatus <span class="token operator">=</span> <span class="token function">OsCurrTaskGet</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-&gt;</span>taskStatus<span class="token punctuation">;</span><span class="token comment">//任务状态先同步，注意这里是赋值操作. ...01101001 </span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>childTaskCB<span class="token operator">-&gt;</span>taskStatus <span class="token operator">&amp;</span> OS_TASK_STATUS_RUNNING<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token comment">//因只能有一个运行的task，所以如果一样要改4号位</span>
        childTaskCB<span class="token operator">-&gt;</span>taskStatus <span class="token operator">&amp;=</span> <span class="token operator">~</span>OS_TASK_STATUS_RUNNING<span class="token punctuation">;</span><span class="token comment">//将四号位清0 ，变成 ...01100001 </span>
    <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span><span class="token comment">//非运行状态下会发生什么？</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>OS_SCHEDULER_ACTIVE<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token comment">//克隆线程发生错误未运行</span>
            <span class="token function">LOS_Panic</span><span class="token punctuation">(</span><span class="token string">&quot;Clone thread status not running error status: 0x%x\n&quot;</span>， childTaskCB<span class="token operator">-&gt;</span>taskStatus<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        childTaskCB<span class="token operator">-&gt;</span>taskStatus <span class="token operator">&amp;=</span> <span class="token operator">~</span>OS_TASK_STATUS_UNUSED<span class="token punctuation">;</span><span class="token comment">//干净的Task</span>
        childProcessCB<span class="token operator">-&gt;</span>priority <span class="token operator">=</span> OS_PROCESS_PRIORITY_LOWEST<span class="token punctuation">;</span><span class="token comment">//进程设为最低优先级</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">OsProcessIsUserMode</span><span class="token punctuation">(</span>childProcessCB<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token comment">//是否是用户进程</span>
        <span class="token function">SCHEDULER_LOCK</span><span class="token punctuation">(</span>intSave<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token function">OsUserCloneParentStack</span><span class="token punctuation">(</span>childTaskCB， <span class="token function">OsCurrTaskGet</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//拷贝当前任务上下文给新的任务</span>
        <span class="token function">SCHEDULER_UNLOCK</span><span class="token punctuation">(</span>intSave<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token function">OS_TASK_PRI_QUEUE_ENQUEUE</span><span class="token punctuation">(</span>childProcessCB， childTaskCB<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//将task加入子进程的就绪队列</span>
    childTaskCB<span class="token operator">-&gt;</span>taskStatus <span class="token operator">|=</span> OS_TASK_STATUS_READY<span class="token punctuation">;</span><span class="token comment">//任务状态贴上就绪标签</span>
    <span class="token keyword">return</span> LOS_OK<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">//把父任务上下文克隆给子任务</span>
LITE_OS_SEC_TEXT VOID <span class="token function">OsUserCloneParentStack</span><span class="token punctuation">(</span>LosTaskCB <span class="token operator">*</span>childTaskCB， LosTaskCB <span class="token operator">*</span>parentTaskCB<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    TaskContext <span class="token operator">*</span>context <span class="token operator">=</span> <span class="token punctuation">(</span>TaskContext <span class="token operator">*</span><span class="token punctuation">)</span>childTaskCB<span class="token operator">-&gt;</span>stackPointer<span class="token punctuation">;</span>
    VOID <span class="token operator">*</span>cloneStack <span class="token operator">=</span> <span class="token punctuation">(</span>VOID <span class="token operator">*</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">(</span>UINTPTR<span class="token punctuation">)</span>parentTaskCB<span class="token operator">-&gt;</span>topOfStack <span class="token operator">+</span> parentTaskCB<span class="token operator">-&gt;</span>stackSize<span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>TaskContext<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token comment">//cloneStack指向 TaskContext</span>
    <span class="token function">LOS_ASSERT</span><span class="token punctuation">(</span>parentTaskCB<span class="token operator">-&gt;</span>taskStatus <span class="token operator">&amp;</span> OS_TASK_STATUS_RUNNING<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//当前任务一定是正在运行的task</span>

    <span class="token punctuation">(</span>VOID<span class="token punctuation">)</span><span class="token function">memcpy_s</span><span class="token punctuation">(</span>childTaskCB<span class="token operator">-&gt;</span>stackPointer， <span class="token keyword">sizeof</span><span class="token punctuation">(</span>TaskContext<span class="token punctuation">)</span>， cloneStack， <span class="token keyword">sizeof</span><span class="token punctuation">(</span>TaskContext<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//直接把任务上下文拷贝了一份</span>
    context<span class="token operator">-&gt;</span>R<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token comment">//R0寄存器为0，这个很重要， pid = fork()  pid == 0 是子进程返回。</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br><span class="line-number">37</span><br><span class="line-number">38</span><br><span class="line-number">39</span><br><span class="line-number">40</span><br><span class="line-number">41</span><br><span class="line-number">42</span><br><span class="line-number">43</span><br><span class="line-number">44</span><br><span class="line-number">45</span><br><span class="line-number">46</span><br><span class="line-number">47</span><br><span class="line-number">48</span><br><span class="line-number">49</span><br><span class="line-number">50</span><br><span class="line-number">51</span><br></div></div><p><strong>解读</strong></p> <ul><li><p>系统调用是通过<code>CLONE_SIGHAND</code>的方式创建子进程的。具体有哪些创建方式如下:</p> <div class="language-c line-numbers-mode"><pre class="language-c"><code>  <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">CLONE_VM</span>       <span class="token expression"><span class="token number">0x00000100</span>	</span><span class="token comment">//子进程与父进程运行于相同的内存空间</span></span>
  <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">CLONE_FS</span>       <span class="token expression"><span class="token number">0x00000200</span>	</span><span class="token comment">//子进程与父进程共享相同的文件系统，包括root、当前目录、umask</span></span>
  <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">CLONE_FILES</span>    <span class="token expression"><span class="token number">0x00000400</span>	</span><span class="token comment">//子进程与父进程共享相同的文件描述符（file descriptor）表</span></span>
  <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">CLONE_SIGHAND</span>  <span class="token expression"><span class="token number">0x00000800</span>	</span><span class="token comment">//子进程与父进程共享相同的信号处理（signal handler）表</span></span>
  <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">CLONE_PTRACE</span>   <span class="token expression"><span class="token number">0x00002000</span>	</span><span class="token comment">//若父进程被trace，子进程也被trace</span></span>
  <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">CLONE_VFORK</span>    <span class="token expression"><span class="token number">0x00004000</span>	</span><span class="token comment">//父进程被挂起，直至子进程释放虚拟内存资源</span></span>
  <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">CLONE_PARENT</span>   <span class="token expression"><span class="token number">0x00008000</span>	</span><span class="token comment">//创建的子进程的父进程是调用者的父进程，新进程与创建它的进程成了“兄弟”而不是“父子”</span></span>
  <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">CLONE_THREAD</span>   <span class="token expression"><span class="token number">0x00010000</span>	</span><span class="token comment">//Linux 2.4中增加以支持POSIX线程标准，子进程与父进程共享相同的线程群</span></span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br></div></div><p>此处不展开细说，进程之间发送信号用于异步通讯，系列篇有专门的篇幅说信号(signal)，请自行翻看。</p></li> <li><p>可以看出fork的主体函数是<code>OsCopyProcess</code>，先申请一个干净的PCB，相当于申请一个容器装资源。</p></li> <li><p>初始化这个容器<code>OsForkInitPCB</code>， <code>OsInitPCB</code> 先把容器打扫干净，虚拟空间，地址映射表(L1表)，各种链表初始化好，为接下来的内容拷贝做好准备。</p></li> <li><p><code>OsCopyParent</code>把家族基因/关系传递给子进程，谁是你的老祖宗，你的七大姑八大姨是谁都得告诉你知道，这些都将挂到你已经初始化好的链表上。</p></li> <li><p><code>OsCopyTask</code>这个很重要，拷贝父进程当前执行的任务数据给子进程的新任务，系列篇中已经说过，真正让CPU干活的是任务(线程)，所以子进程需要创建一个新任务 <code>LOS_TaskCreateOnly</code>来接受当前任务的数据，这个数据包括栈的数据，运行代码段指向，<code>OsUserCloneParentStack</code>将用户态的上下文数据<code>TaskContext</code>拷贝到子进程新任务的栈底位置， 也就是说新任务运行栈中此时只有上下文的数据。而且有最最最重要的一句代码 <code>context-&gt;R[0] = 0;</code> 强制性的将未来恢复上下文<code>R0</code>寄存器的数据改成了0， 这意味着调度算法切到子进程的任务后， 任务干的第一件事是恢复上下文，届时<code>R0</code>寄存器的值变成0，而<code>R0=0</code>意味着什么？ 同时<code>LR/SP</code>寄存器的值也和父进程的一样。这又意味着什么？</p></li> <li><p>系列篇寄存器篇中以说过返回值就是存在R0寄存器中，<code>A()-&gt;B()</code>，A拿B的返回值只认<code>R0</code>的数据，读到什么就是什么返回值，而R0寄存器值等于0，等同于获得返回值为0， 而LR寄存器所指向的指令是<code>pid=返回值</code>， sp寄存器记录了栈中的开始计算的位置，如此完全还原了父进程调用<code>fork()</code>前的运行场景，唯一的区别是改变了<code>R0</code>寄存器的值，所以才有了</p> <div class="language-c line-numbers-mode"><pre class="language-c"><code>pid <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token comment">//fork()的返回值，注意子进程并没有执行fork()，它只是通过恢复上下文获得了一个返回值。</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>pid <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  	message <span class="token operator">=</span> <span class="token string">&quot;This is the child\n&quot;</span><span class="token punctuation">;</span>
  	n <span class="token operator">=</span> <span class="token number">6</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div><p>由此确保了这是子进程的返回。这是<code>fork()</code>最精彩的部分。一定要好好理解。<code>OsCopyTask``OsUserCloneParentStack</code>的代码细节。会让你醍醐灌顶，永生难忘。</p></li> <li><p>父进程的返回是<code>processID = child-&gt;processID;</code>是子进程的ID，任何子进程的ID是不可能等于0的，成功了只能是大于0。 失败了就是负数 <code>return -ret;</code></p></li> <li><p><code>OsCopyProcessResources</code>用于赋值各种资源，包括拷贝虚拟空间内存，拷贝打开的文件列表，IPC等等。</p></li> <li><p><code>OsChildSetProcessGroupAndSched</code>设置子进程组和调度的准备工作，加入调度队列，准备调度。</p></li> <li><p><code>LOS_MpSchedule</code>是个核间中断，给所有CPU发送调度信号，让所有CPU发生一次调度。由此父进程让出CPU使用权，因为子进程的调度优先级和父进程是平级，而同级情况下子进程的任务已经插到就绪队列的头部位置 <code>OS_PROCESS_PRI_QUEUE_ENQUEUE</code>排在了父进程任务的前面，所以在没有比他们更高优先级的进程和任务出现之前，下一次被调度到的任务就是子进程的任务。也就是在本篇开头看到的</p> <div class="language-c line-numbers-mode"><pre class="language-c"><code>$ <span class="token punctuation">.</span><span class="token operator">/</span>a<span class="token punctuation">.</span>out 
This is the child
This is the parent
This is the child
This is the parent
This is the child
This is the parent
This is the child
$ This is the child
This is the child
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br></div></div></li> <li><p>以上为fork在鸿蒙内核的整个实现过程，务必结合系列篇其他篇理解，一次理解透彻，终生不忘。</p></li></ul> <h3 id="百文说内核-抓住主脉络">百文说内核 | 抓住主脉络</h3> <ul><li>百文相当于摸出内核的肌肉和器官系统，让人开始丰满有立体感，因是直接从注释源码起步，在加注释过程中，每每有心得处就整理,慢慢形成了以下文章。内容立足源码，常以生活场景打比方尽可能多的将内核知识点置入某种场景，具有画面感，容易理解记忆。说别人能听得懂的话很重要! 百篇博客绝不是百度教条式的在说一堆诘屈聱牙的概念，那没什么意思。更希望让内核变得栩栩如生，倍感亲切。</li> <li>与代码需不断<code>debug</code>一样，文章内容会存在不少错漏之处，请多包涵，但会反复修正，持续更新，<code>v**.xx</code> 代表文章序号和修改的次数，精雕细琢，言简意赅，力求打造精品内容。</li> <li>百文在 &lt; 鸿蒙研究站 | 开源中国 | 博客园 | 51cto | csdn | 知乎 | 掘金 &gt; 站点发布，百篇博客系列目录如下。</li> <li><img src="https://weharmonyos.oss-cn-hangzhou.aliyuncs.com/resources/common/cate.png" alt=""></li></ul> <p>按功能模块:</p> <table><thead><tr><th style="text-align:center;">基础知识</th> <th style="text-align:center;">进程管理</th> <th style="text-align:center;">任务管理</th> <th style="text-align:center;">内存管理</th></tr></thead> <tbody><tr><td style="text-align:center;"><a href="http://weharmonyos.com/blog/01.html" target="_blank" rel="noopener noreferrer">双向链表</a><br><a href="http://weharmonyos.com/blog/02.html" target="_blank" rel="noopener noreferrer">内核概念</a><br><a href="http://weharmonyos.com/blog/03.html" target="_blank" rel="noopener noreferrer">源码结构</a><br><a href="http://weharmonyos.com/blog/04.html" target="_blank" rel="noopener noreferrer">地址空间</a><br><a href="http://weharmonyos.com/blog/05.html" target="_blank" rel="noopener noreferrer">计时单位</a><br><a href="http://weharmonyos.com/blog/06.html" target="_blank" rel="noopener noreferrer">优雅的宏</a><br><a href="http://weharmonyos.com/blog/07.html" target="_blank" rel="noopener noreferrer">钩子框架</a><br><a href="http://weharmonyos.com/blog/08.html" target="_blank" rel="noopener noreferrer">位图管理</a><br><a href="http://weharmonyos.com/blog/09.html" target="_blank" rel="noopener noreferrer">POSIX</a><br><a href="http://weharmonyos.com/blog/10.html" target="_blank" rel="noopener noreferrer">main函数</a><br></td> <td style="text-align:center;"><a href="http://weharmonyos.com/blog/11.html" target="_blank" rel="noopener noreferrer">调度故事</a><br><a href="http://weharmonyos.com/blog/12.html" target="_blank" rel="noopener noreferrer">进程控制块</a><br><a href="http://weharmonyos.com/blog/13.html" target="_blank" rel="noopener noreferrer">进程空间</a><br><a href="http://weharmonyos.com/blog/14.html" target="_blank" rel="noopener noreferrer">线性区</a><br><a href="http://weharmonyos.com/blog/15.html" target="_blank" rel="noopener noreferrer">红黑树</a><br><a href="http://weharmonyos.com/blog/16.html" target="_blank" rel="noopener noreferrer">进程管理</a><br><a href="http://weharmonyos.com/blog/17.html" target="_blank" rel="noopener noreferrer">Fork进程</a><br><a href="http://weharmonyos.com/blog/18.html" target="_blank" rel="noopener noreferrer">进程回收</a><br><a href="http://weharmonyos.com/blog/19.html" target="_blank" rel="noopener noreferrer">Shell编辑</a><br><a href="http://weharmonyos.com/blog/20.html" target="_blank" rel="noopener noreferrer">Shell解析</a><br></td> <td style="text-align:center;"><a href="http://weharmonyos.com/blog/21.html" target="_blank" rel="noopener noreferrer">任务控制块</a><br><a href="http://weharmonyos.com/blog/22.html" target="_blank" rel="noopener noreferrer">并发并行</a><br><a href="http://weharmonyos.com/blog/23.html" target="_blank" rel="noopener noreferrer">就绪队列</a><br><a href="http://weharmonyos.com/blog/24.html" target="_blank" rel="noopener noreferrer">调度机制</a><br><a href="http://weharmonyos.com/blog/25.html" target="_blank" rel="noopener noreferrer">任务管理</a><br><a href="http://weharmonyos.com/blog/26.html" target="_blank" rel="noopener noreferrer">用栈方式</a><br><a href="http://weharmonyos.com/blog/27.html" target="_blank" rel="noopener noreferrer">软件定时器</a><br><a href="http://weharmonyos.com/blog/28.html" target="_blank" rel="noopener noreferrer">控制台</a><br><a href="http://weharmonyos.com/blog/29.html" target="_blank" rel="noopener noreferrer">远程登录</a><br><a href="http://weharmonyos.com/blog/30.html" target="_blank" rel="noopener noreferrer">协议栈</a><br></td> <td style="text-align:center;"><a href="http://weharmonyos.com/blog/31.html" target="_blank" rel="noopener noreferrer">内存规则</a><br><a href="http://weharmonyos.com/blog/32.html" target="_blank" rel="noopener noreferrer">物理内存</a><br><a href="http://weharmonyos.com/blog/33.html" target="_blank" rel="noopener noreferrer">内存概念</a><br><a href="http://weharmonyos.com/blog/34.html" target="_blank" rel="noopener noreferrer">虚实映射</a><br><a href="http://weharmonyos.com/blog/35.html" target="_blank" rel="noopener noreferrer">页表管理</a><br><a href="http://weharmonyos.com/blog/36.html" target="_blank" rel="noopener noreferrer">静态分配</a><br><a href="http://weharmonyos.com/blog/37.html" target="_blank" rel="noopener noreferrer">TLFS算法</a><br><a href="http://weharmonyos.com/blog/38.html" target="_blank" rel="noopener noreferrer">内存池管理</a><br><a href="http://weharmonyos.com/blog/39.html" target="_blank" rel="noopener noreferrer">原子操作</a><br><a href="http://weharmonyos.com/blog/40.html" target="_blank" rel="noopener noreferrer">圆整对齐</a><br></td></tr> <tr><td style="text-align:center;">通讯机制</td> <td style="text-align:center;">文件系统</td> <td style="text-align:center;">硬件架构</td> <td style="text-align:center;">内核汇编</td></tr> <tr><td style="text-align:center;"><a href="http://weharmonyos.com/blog/41.html" target="_blank" rel="noopener noreferrer">通讯总览</a><br><a href="http://weharmonyos.com/blog/42.html" target="_blank" rel="noopener noreferrer">自旋锁</a><br><a href="http://weharmonyos.com/blog/43.html" target="_blank" rel="noopener noreferrer">互斥锁</a><br><a href="http://weharmonyos.com/blog/44.html" target="_blank" rel="noopener noreferrer">快锁使用</a><br><a href="http://weharmonyos.com/blog/45.html" target="_blank" rel="noopener noreferrer">快锁实现</a><br><a href="http://weharmonyos.com/blog/46.html" target="_blank" rel="noopener noreferrer">读写锁</a><br><a href="http://weharmonyos.com/blog/47.html" target="_blank" rel="noopener noreferrer">信号量</a><br><a href="http://weharmonyos.com/blog/48.html" target="_blank" rel="noopener noreferrer">事件机制</a><br><a href="http://weharmonyos.com/blog/49.html" target="_blank" rel="noopener noreferrer">信号生产</a><br><a href="http://weharmonyos.com/blog/50.html" target="_blank" rel="noopener noreferrer">信号消费</a><br><a href="http://weharmonyos.com/blog/51.html" target="_blank" rel="noopener noreferrer">消息队列</a><br><a href="http://weharmonyos.com/blog/52.html" target="_blank" rel="noopener noreferrer">消息封装</a><br><a href="http://weharmonyos.com/blog/53.html" target="_blank" rel="noopener noreferrer">消息映射</a><br><a href="http://weharmonyos.com/blog/54.html" target="_blank" rel="noopener noreferrer">共享内存</a><br></td> <td style="text-align:center;"><a href="http://weharmonyos.com/blog/55.html" target="_blank" rel="noopener noreferrer">文件概念</a><br><a href="http://weharmonyos.com/blog/56.html" target="_blank" rel="noopener noreferrer">文件故事</a><br><a href="http://weharmonyos.com/blog/57.html" target="_blank" rel="noopener noreferrer">索引节点</a><br><a href="http://weharmonyos.com/blog/58.html" target="_blank" rel="noopener noreferrer">VFS</a><br><a href="http://weharmonyos.com/blog/59.html" target="_blank" rel="noopener noreferrer">文件句柄</a><br><a href="http://weharmonyos.com/blog/60.html" target="_blank" rel="noopener noreferrer">根文件系统</a><br><a href="http://weharmonyos.com/blog/61.html" target="_blank" rel="noopener noreferrer">挂载机制</a><br><a href="http://weharmonyos.com/blog/62.html" target="_blank" rel="noopener noreferrer">管道文件</a><br><a href="http://weharmonyos.com/blog/63.html" target="_blank" rel="noopener noreferrer">文件映射</a><br><a href="http://weharmonyos.com/blog/64.html" target="_blank" rel="noopener noreferrer">写时拷贝</a><br></td> <td style="text-align:center;"><a href="http://weharmonyos.com/blog/65.html" target="_blank" rel="noopener noreferrer">芯片模式</a><br><a href="http://weharmonyos.com/blog/66.html" target="_blank" rel="noopener noreferrer">ARM架构</a><br><a href="http://weharmonyos.com/blog/67.html" target="_blank" rel="noopener noreferrer">指令集</a><br><a href="http://weharmonyos.com/blog/68.html" target="_blank" rel="noopener noreferrer">协处理器</a><br><a href="http://weharmonyos.com/blog/69.html" target="_blank" rel="noopener noreferrer">工作模式</a><br><a href="http://weharmonyos.com/blog/70.html" target="_blank" rel="noopener noreferrer">寄存器</a><br><a href="http://weharmonyos.com/blog/71.html" target="_blank" rel="noopener noreferrer">多核管理</a><br><a href="http://weharmonyos.com/blog/72.html" target="_blank" rel="noopener noreferrer">中断概念</a><br><a href="http://weharmonyos.com/blog/73.html" target="_blank" rel="noopener noreferrer">中断管理</a><br></td> <td style="text-align:center;"><a href="http://weharmonyos.com/blog/74.html" target="_blank" rel="noopener noreferrer">编码方式</a><br><a href="http://weharmonyos.com/blog/75.html" target="_blank" rel="noopener noreferrer">汇编基础</a><br><a href="http://weharmonyos.com/blog/76.html" target="_blank" rel="noopener noreferrer">汇编传参</a><br><a href="http://weharmonyos.com/blog/77.html" target="_blank" rel="noopener noreferrer">链接脚本</a><br><a href="http://weharmonyos.com/blog/78.html" target="_blank" rel="noopener noreferrer">内核启动</a><br><a href="http://weharmonyos.com/blog/79.html" target="_blank" rel="noopener noreferrer">进程切换</a><br><a href="http://weharmonyos.com/blog/80.html" target="_blank" rel="noopener noreferrer">任务切换</a><br><a href="http://weharmonyos.com/blog/81.html" target="_blank" rel="noopener noreferrer">中断切换</a><br><a href="http://weharmonyos.com/blog/82.html" target="_blank" rel="noopener noreferrer">异常接管</a><br><a href="http://weharmonyos.com/blog/83.html" target="_blank" rel="noopener noreferrer">缺页中断</a><br></td></tr> <tr><td style="text-align:center;">编译运行</td> <td style="text-align:center;">调测工具</td> <td style="text-align:center;"></td> <td style="text-align:center;"></td></tr> <tr><td style="text-align:center;"><a href="http://weharmonyos.com/blog/84.html" target="_blank" rel="noopener noreferrer">编译过程</a><br><a href="http://weharmonyos.com/blog/85.html" target="_blank" rel="noopener noreferrer">编译构建</a><br><a href="http://weharmonyos.com/blog/86.html" target="_blank" rel="noopener noreferrer">GN语法</a><br><a href="http://weharmonyos.com/blog/87.html" target="_blank" rel="noopener noreferrer">忍者无敌</a><br><a href="http://weharmonyos.com/blog/88.html" target="_blank" rel="noopener noreferrer">ELF格式</a><br><a href="http://weharmonyos.com/blog/89.html" target="_blank" rel="noopener noreferrer">ELF解析</a><br><a href="http://weharmonyos.com/blog/90.html" target="_blank" rel="noopener noreferrer">静态链接</a><br><a href="http://weharmonyos.com/blog/91.html" target="_blank" rel="noopener noreferrer">重定位</a><br><a href="http://weharmonyos.com/blog/92.html" target="_blank" rel="noopener noreferrer">动态链接</a><br><a href="http://weharmonyos.com/blog/93.html" target="_blank" rel="noopener noreferrer">进程映像</a><br><a href="http://weharmonyos.com/blog/94.html" target="_blank" rel="noopener noreferrer">应用启动</a><br><a href="http://weharmonyos.com/blog/95.html" target="_blank" rel="noopener noreferrer">系统调用</a><br><a href="http://weharmonyos.com/blog/96.html" target="_blank" rel="noopener noreferrer">VDSO</a><br></td> <td style="text-align:center;"><a href="http://weharmonyos.com/blog/97.html" target="_blank" rel="noopener noreferrer">模块监控</a><br><a href="http://weharmonyos.com/blog/98.html" target="_blank" rel="noopener noreferrer">日志跟踪</a><br><a href="http://weharmonyos.com/blog/99.html" target="_blank" rel="noopener noreferrer">系统安全</a><br><a href="http://weharmonyos.com/blog/100.html" target="_blank" rel="noopener noreferrer">测试用例</a><br></td> <td style="text-align:center;"></td> <td style="text-align:center;"></td></tr></tbody></table> <h3 id="百万注源码-处处扣细节">百万注源码 | 处处扣细节</h3> <ul><li><p>百万汉字注解内核目的是要看清楚其毛细血管，细胞结构，等于在拿放大镜看内核。内核并不神秘，带着问题去源码中找答案是很容易上瘾的，你会发现很多文章对一些问题的解读是错误的，或者说不深刻难以自圆其说，你会慢慢形成自己新的解读，而新的解读又会碰到新的问题，如此层层递进，滚滚向前，拿着放大镜根本不愿意放手。</p></li> <li><p><a href="https://gitee.com/weharmony/kernel_liteos_a_note" target="_blank" rel="noopener noreferrer">&lt; gitee</a> | <a href="https://github.com/kuangyufei/kernel_liteos_a_note" target="_blank" rel="noopener noreferrer">github</a> | <a href="https://weharmony.coding.net/public/harmony/kernel_liteos_a_note/git/files" target="_blank" rel="noopener noreferrer">coding</a> | <a href="https://gitcode.net/kuangyufei/kernel_liteos_a_note" target="_blank" rel="noopener noreferrer">gitcode &gt;</a> 四大码仓推送 | 同步官方源码。</p> <p><a href="https://gitee.com/weharmony/kernel_liteos_a_note" target="_blank" rel="noopener noreferrer"><img src="https://gitee.com/weharmony/kernel_liteos_a_note/widgets/widget_card.svg?colors=393222,ebdfc1,fffae5,d8ca9f,393222,a28b40" alt=""></a></p></li></ul> <h3 id="关注不迷路-代码即人生">关注不迷路 | 代码即人生</h3> <p><img src="https://weharmonyos.oss-cn-hangzhou.aliyuncs.com/resources/common/so1so.png" alt=""></p> <ul><li>互联网从业十五年，计算机硕士，技术副总裁</li> <li>关注我，持续更新四十年，即聊技术也聊人生</li> <li>交有趣靠谱的人；做难而正确的事</li> <li>不做作，不炒作，只唯真</li> <li>不唯上，不唯书，只唯实</li></ul> <p><a href="http://weharmonyos.com/donate.html" target="_blank" rel="noopener noreferrer"> &gt;&gt; 捐助名单</a></p> <p>据说喜欢 <strong>点赞 + 分享</strong> 的,后来都成了大神。😃</p></div> <!----> <div class="content__content-bottom"></div> <footer class="page-meta"><!----> <!----> <!----></footer> <div class="page-nav"><p class="inner"><span class="prev"><a href="/blog/16.html" class="prev"><svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" class="icon prev-icon"><path d="M906.783 588.79c-.02 8.499-6.882 15.36-15.38 15.37l-443.7-.01 75.704 191.682c2.52 6.42.482 13.763-5.038 17.91-5.52 4.168-13.138 4.147-18.616-.092L123.228 524.175a15.362 15.362 0 0 1-6-12.165c0-4.782 2.222-9.277 6-12.185L499.753 210.35a15.388 15.388 0 0 1 9.38-3.195c3.236 0 6.502 1.034 9.236 3.103 5.52 4.147 7.578 11.49 5.038 17.91L447.683 419.84l443.72-.01c8.498.01 15.36 6.881 15.36 15.36l.02 153.6z" fill="currentColor"></path></svg>
        进程管理
      </a></span> <span class="next"><a href="/blog/18.html">
        进程回收
        <svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" class="icon next-icon"><path d="M906.772 512c0 4.772-2.211 9.267-5.99 12.175L524.257 813.66a15.37 15.37 0 0 1-18.616.092 15.368 15.368 0 0 1-5.038-17.91l75.714-191.672h-443.73c-8.488 0-15.36-6.881-15.36-15.36v-153.6c0-8.489 6.872-15.36 15.36-15.36h443.73l-75.714-191.682a15.358 15.358 0 0 1 5.048-17.91c5.51-4.158 13.128-4.137 18.606.092l376.525 289.485a15.323 15.323 0 0 1 5.99 12.165z" fill="currentColor"></path></svg></a></span></p></div> <!----> <!----> <div class="content__page-bottom"></div></main> <!----></div><div class="global-ui"><!----><!----><div id="pwa-install"><!----> <div id="install-modal-wrapper" style="display:none;"><div class="background"></div> <div class="install-modal"><div class="header"><button aria-label="Close" class="close-button"><svg width="23" height="22" xmlns="http://www.w3.org/2000/svg" class="icon close-icon"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.12.358a1.224 1.224 0 011.729 0l8.92 8.914L20.686.358a1.224 1.224 0 011.73 1.728L13.497 11l8.92 8.913a1.222 1.222 0 11-1.73 1.729l-8.919-8.913-8.92 8.913a1.224 1.224 0 01-1.729-1.729L10.04 11l-8.92-8.914a1.222 1.222 0 010-1.728z" fill="currentColor"></path></svg></button> <div class="logo"><!----> <div class="title"><h1></h1> <p class="desc">This app can be installed on your PC or mobile device.  This will allow this web app to look and behave like any other installed app.  You will find it in your app lists and be able to pin it to your home screen, start menus or task bars.  This installed web app will also be able to safely interact with other apps and your operating system. </p></div></div></div> <div class="content"><div class="highlight"><!----> <!----></div> <div class="description"><h3>Description</h3> <p></p></div></div> <div class="button-wrapper"><button class="install-button">
        Install <span></span></button> <button class="cancel-button">
        Cancel
      </button></div></div></div></div><div tabindex="-1" role="dialog" aria-hidden="true" class="pswp"><div class="pswp__bg"></div> <div class="pswp__scroll-wrap"><div class="pswp__container"><div class="pswp__item"></div> <div class="pswp__item"></div> <div class="pswp__item"></div></div> <div class="pswp__ui pswp__ui--hidden"><div class="pswp__top-bar"><div class="pswp__counter"></div> <button title="Close" aria-label="Close" class="pswp__button pswp__button--close"></button> <button title="Share" aria-label="Share" class="pswp__button pswp__button--share"></button> <button title="Switch to full screen" aria-label="Switch to full screen" class="pswp__button pswp__button--fs"></button> <button title="Zoom in/out" aria-label="Zoom in/out" class="pswp__button pswp__button--zoom"></button> <div class="pswp__preloader"><div class="pswp__preloader__icn"><div class="pswp__preloader__cut"><div class="pswp__preloader__donut"></div></div></div></div></div> <div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap"><div class="pswp__share-tooltip"></div></div> <button title="Prev (Arrow Left)" aria-label="Prev (Arrow Left)" class="pswp__button pswp__button--arrow--left"></button> <button title="Next (Arrow Right)" aria-label="Next (Arrow Right)" class="pswp__button pswp__button--arrow--right"></button> <div class="pswp__caption"><div class="pswp__caption__center"></div></div></div></div></div></div></div>
    <script src="/assets/js/app.9a8b95d8.js" defer></script><script src="/assets/js/vendors~layout-Layout.c1e797d4.js" defer></script><script src="/assets/js/vendors~layout-Blog~layout-Layout~layout-NotFound.f75cf258.js" defer></script><script src="/assets/js/page--ba329370.b5f22d13.js" defer></script>
  </body>
</html>
